package org.example.everyday;

import jdk.internal.org.objectweb.asm.tree.LineNumberNode;

import java.util.*;

/**
 * <p>
 * Description:TODO 详细描述
 * <p>
 * <p>
 *
 * @author anlu
 * @date 2022/7/6 0006 12:13
 */
public class Lc736 {
    Map<String, Deque<Integer>> scope = new HashMap<String,Deque<Integer>>();
    int start = 0;

    public static void main(String[] args) {
        Lc736 lc736 = new Lc736();

       String expression = "(let x 2 (mult x (let x 3 y 4 (add x y))))";
       int res = lc736.evaluate(expression);
        System.out.println(res);
    }

    public int evaluate(String expression) {
        return innerEvaluate(expression);
    }



    public int innerEvaluate(String expression){
        //非表达式，可能为整数或者变量
        if(expression.charAt(start) != '('){
            if(Character.isLowerCase(expression.charAt(start))){
                //变量
                String var = parseVar(expression);
                return scope.get(var).peek();
            }else{
                return parseInt(expression);
            }
        }

        int ret;
        //移除左括号
        start++;
        if(expression.charAt(start) == 'l'){
            start += 4;
            List<String> vars = new ArrayList<String>();
            while (true){
                if(!Character.isLowerCase(expression.charAt(start))){
                    //let表达式的最后一个expr表达式的值
                    ret = innerEvaluate(expression);
                    break;
                }
                String var = parseVar(expression);
                if(expression.charAt(start) == ')'){
                    ret = scope.get(var).peek();
                    break;
                }
                vars.add(var);
                start++;
                int e = innerEvaluate(expression);

                scope.putIfAbsent(var,new ArrayDeque<Integer>());
                scope.get(var).push(e);
                start++;
            }
            for(String var : vars){
                scope.get(var).pop();
            }

        } else if(expression.charAt(start) == 'a'){
            start += 4;
            int e1 = innerEvaluate(expression);
            start++;
            int e2 = innerEvaluate(expression);
            start++;
            ret = e1 + e2;
        }else{
            start += 5; // 移除 "mult "
            int e1 = innerEvaluate(expression);
            start++; // 移除空格
            int e2 = innerEvaluate(expression);

            ret = e1 * e2;
        }
        start++;
        return ret;
    }


    private int parseInt(String expression){
        int n = expression.length();
        int ret = 0, sign = 1;
        if(expression.charAt(start) == '-'){
            sign = -1;
            start++;
        }
        while (start < n && Character.isDigit(expression.charAt(start))){
            ret = ret * 10 +(expression.charAt(start) - '0');
            start++;
        }
        return sign * ret;
    }

    private String parseVar(String expression){
        int n = expression.length();
        StringBuffer ret = new StringBuffer();
        while (start < n && expression.charAt(start) != ' ' && expression.charAt(start) != ')'){
            ret.append(expression.charAt(start));
            start++;
        }
        return ret.toString();
    }
}
